/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.generator.baseInfo;

import java.util.HashMap;
import java.util.Map.Entry;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;

/**
 * @author liu_wei
 */
public class AnnotationInfo extends BaseGenerateInfo {

    private TypeInfo typeInfo;
    private HashMap<String, Expression> params = new HashMap<String, Expression>();
    private Expression singleParam;

    private AnnotationType annotationType = AnnotationType.Normal;
    private Annotation annotation;

    public void setSingleParam(Expression singleParam) {
        this.singleParam = singleParam;
    }

    public void setTypeInfo(TypeInfo typeInfo) {
        this.typeInfo = typeInfo;
    }

    public TypeInfo getTypeInfo() {
        return typeInfo;
    }

    public void setAnnotationType(AnnotationType annotationType) {
        this.annotationType = annotationType;
    }

    public HashMap<String, Expression> getParams() {
        return params;
    }

    public void setParams(HashMap<String, Expression> params) {
        this.params = params;
    }

    @Override
    void generate() {
        switch (annotationType) {
            case Normal:
                annotation = getNormalAnnotation();
                break;
            case Marker:
                annotation = getMarkerAnnotation();
                break;
            case SingleMember:
                annotation = getSingleMemberAnnotation();
                break;
            default:
                annotation = null;
        }

    }

    private SingleMemberAnnotation getSingleMemberAnnotation() {
        SingleMemberAnnotation singleAnnotation = ast.newSingleMemberAnnotation();
        singleAnnotation.setTypeName(ast.newSimpleName(typeInfo.getTypeName()));
        singleAnnotation.setValue(singleParam);
        return singleAnnotation;
    }

    private MarkerAnnotation getMarkerAnnotation() {
        MarkerAnnotation markerAnnotation = ast.newMarkerAnnotation();
        markerAnnotation.setTypeName(ast.newSimpleName(typeInfo.getTypeName()));
        return markerAnnotation;
    }

    private NormalAnnotation getNormalAnnotation() {
        try {
            NormalAnnotation normalAnnotation = ast.newNormalAnnotation();
            normalAnnotation.setTypeName(ast.newName(typeInfo.getTypeName()));
            for (Entry<String, Expression> item : params.entrySet()) {
                SimpleName key = ast.newSimpleName(item.getKey());
                MemberValuePair member = ast.newMemberValuePair();
                member.setName(key);
                member.setValue(item.getValue());
                normalAnnotation.values().add(member);
            }
            return normalAnnotation;
        } catch (RuntimeException e) {
            throw e;
        }

    }

    public Annotation getAnnotation(AST ast) {
        this.ast = ast;
        generate();
        return annotation;
    }

}
